public class Game{
        private Board  board;
        private Player player1;
        private Player player2;
        private Pieces cur_player;
        private GameStatus status; 
        private GameStatus save_status; 
        private Action next_act;

        private int kill_num;

        public Game(int level, int board_size){
                player1 = PlayerFactory.createPlayer(1, Pieces.P1, (board_size *board_size)/2, true);
                player2 = PlayerFactory.createPlayer(3, Pieces.P2, (board_size *board_size)/2, false);
                board = new Board(board_size,board_size);

                System.out.println(player1);
                System.out.println(player2);
                cur_player = Pieces.P1;
                status = GameStatus.GAME_SET;
                save_status = GameStatus.GAME_SET;
                next_act = new Action();
                kill_num = 0;

        }
        public Player getRivalPlayer(){
                if(cur_player == player1.getWho())
                       return player2;
                if(cur_player == player2.getWho())
                       return player1;

                return player1;
        }
        public void chgPlayer(){
                if(cur_player == player1.getWho())
                        cur_player = player2.getWho();
                else if(cur_player == player2.getWho())
                        cur_player = player1.getWho();
        }
        public Player getPlayer(Pieces who){
                if(who == player1.getWho())
                        return player1;
                if(who == player2.getWho())
                        return player2;

                return player1;
        }
        public boolean doNextStep(Action act){
                boolean chg_player = false;
                Point src_pos = new Point();
                Point dst_pos = new Point();

                src_pos = act.src_pos;
                dst_pos = act.dst_pos;
                switch(status){
                        case GAME_SET:
                                src_pos = act.src_pos;
                                if(!board.setPieces(src_pos, cur_player))
                                        break;
                                kill_num = board.getKills(src_pos, cur_player);
                                if(act.player.decFreePieces()){
                                        kill_num++;
                                        save_status = GameStatus.GAME_SET;
                                        if(cur_player == Pieces.P2){
                                            save_status = GameStatus.GAME_SET_LAST;
                                            status = GameStatus.GAME_KILL;
                                            break;
                                        }
                                }
                                if(kill_num > 0){
                                        save_status  = GameStatus.GAME_SET;
                                        status = GameStatus.GAME_KILL;
                                }else{
                                        chg_player = true;
                                }
                                break;
                        case GAME_KILL:
                                src_pos = act.src_pos;
                                if(!board.killPieces(src_pos, act.kill_who, save_status)){
                                        break;
                                }
                                if(act.player.decSetPieces() && save_status != GameStatus.GAME_SET){
                                        status = GameStatus.GAME_OVER;
                                        break;
                                }
                                kill_num--;
                                if(kill_num == 0){
                                        status = save_status;
                                        chg_player = true;
                                }
                                break;
                        case GAME_SET_LAST:
                                board.cleanForbid();
                                status = GameStatus.GAME_MOVE;
                                break;
                        case GAME_MOVE:
                                if(!board.movePieces(src_pos, dst_pos, cur_player)){
                                        break;
                                }
                                kill_num = board.getKills(dst_pos, cur_player);
                                if(kill_num > 0){
                                        save_status = status;
                                        status = GameStatus.GAME_KILL;
                                }else{
                                        chg_player = true;
                                }
                                break;
                        case GAME_OVER:
                                break;
                }
                if(chg_player)
                        chgPlayer();
                return chg_player;
        }
        public void waitAct(){
                if(!getPlayer(cur_player).getIsHuman()){
                        return ;
                }
                while(!human_message){
                        Thread.sleep(5);
                }
        }
        final Thread mThread = new Thread() {
             mChildHandler = new Handler(){
                     public void handleMessage(Message msg){
                             if(!getPlayer(cur_player).getIsHuman() || human_message){
                                     return ;
                             }
                             human_message = true;
                     }
             }
             @Override
             public void run(){
                next_act.status = status;
                next_act.kill_who = getRivalPlayer().getWho();
                while(status != GameStatus.GAME_OVER){
                        waitAct();
                        next_act.status = status;
                        if(getPlayer(cur_player).getNextStep(next_act, board)){
                            doNextStep(next_act);
                            next_act.kill_who = getRivalPlayer().getWho();
                        }else{
                            save_status = status;
                            status = GameStatus.GAME_KILL;
                            kill_num = 1;
                            next_act.kill_who = cur_player;
                        }
                        human_message = false;
                        sendUpdate();
                }
                System.out.println("Winner is " + getRivalPlayer());
             }
        };
}
